package com.gitee.wsl.collections.queue

import com.gitee.wsl.coroutines.atomic.Condition
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

class NotBlockingPriorityQueue<T>(private val capacity: Int) {
    private val queue = ArrayQueue<T>()
    private val mutex = Mutex()
    private val notEmpty = Condition(mutex)
    private val notFull = Condition(mutex)

    suspend fun put(item: T) {
        mutex.withLock {
            while (queue.size == capacity) {
                notFull.await()
            }
            queue.add(item)
            notEmpty.signal()
        }
    }

    suspend fun take(): T {
        return mutex.withLock {
            while (queue.isEmpty()) {
                notEmpty.await()
            }
            val item = queue.poll()
            notFull.signal()
            item
        }
    }
}
